package lv.dysnomia.portal.web

import lv.dysnomia.server.entities.LilypondDAO
import lv.dysnomia.songs.server.wiki.WikiParser
import lv.dysnomia.songs.server.wiki.WikiProc
import lv.dysnomia.server.entities.Lilypond
import lv.dysnomia.songs.server.controllers.SongController
import com.google.appengine.api.datastore.Text
import java.util.Date
import java.io.{ IOException, PrintWriter }
import scala.collection.immutable.Map

import javax.servlet.{ RequestDispatcher, ServletException }
import javax.servlet.http.{ HttpServlet, HttpServletRequest, HttpServletResponse }
import com.google.appengine.api.blobstore.{ BlobKey, BlobInfo, BlobInfoFactory, BlobstoreServiceFactory }

import java.util.{ List => JavaList }
import javax.jdo.{ PersistenceManager, Query }

import lv.dysnomia.server.entities.{ Song, SongDAO, MediaFile, MediaFileDAO }

import com.google.appengine.api.users.{ User, UserService, UserServiceFactory }

class AdminController extends AbstractController {

  val blobstoreService = BlobstoreServiceFactory.getBlobstoreService
  val blobInfoFactory = new BlobInfoFactory

  def modelAndView(request: HttpServletRequest, response: HttpServletResponse): (Map[String, AnyRef], String) = {

    val userService = UserServiceFactory.getUserService
    val user = userService.getCurrentUser
    if (!userService.isUserLoggedIn) return (Map.empty[String, AnyRef], "not-logged-in")
    if (!userService.isUserAdmin) return (Map.empty[String, AnyRef], "not-allowed")
    val pathInfo = request.getPathInfo
    val method = request.getMethod
    pathInfo match {
      case "/delete-ask.html" => deleteAsk(request.getParameter("label"))
      case "/delete-song.html" => deleteSong(request.getParameter("label"))
      case "/edit-song.html" => editSong(request.getParameter("label"))
      case "/index.html" => index
      case "/upload.html" => upload
      case "/delete-blob.html" => deleteBlob(request.getParameter("blob-key"))
      case "/list-media.html" => listMedia
      case "/new-song.html" => newSong
      case "/save-song.html" => SongController.saveSong(request.getParameter("title"),
        request.getParameter("lyrics"), 
        user.getUserId,
        if (request.getParameter("label") == null) ""
        else request.getParameter("label"),
        request.getParameter("lilypond"),
        request.getParameter("pngLink"), 
        request.getParameter("svgLink"), 
        request.getParameter("midiLink"),
        request.getParameter("oggLink"))
      case "/remove-all.html" => {
        if (!method.equalsIgnoreCase("POST"))
          (Map("pathInfo" -> pathInfo, "method" -> method), "notFound")
        else removeAll
      }
      case _ => (Map("pathInfo" -> pathInfo), "notFound")
    }
  }

  def index(): (Map[String, AnyRef], String) = (Map.empty[String, AnyRef], "index")

  def upload(): (Map[String, AnyRef], String) = (Map.empty[String, AnyRef], "upload")

  def newSong(): (Map[String, AnyRef], String) = (Map.empty[String, AnyRef], "new-song")

  def removeAll(): (Map[String, AnyRef], String) = {
    val removed: Long = 0;
    try {
      val removed = SongDAO.removeAll
      println("removed = " + removed)
      return (Map("removed" -> removed.asInstanceOf[AnyRef]), "remove-all")
    } catch {
      case e => e.printStackTrace
    }
    (Map.empty[String, AnyRef], "remove-all")
  }

  def listMedia(): (Map[String, AnyRef], String) = {
    val pm: PersistenceManager = PMF.getInstance.getPersistenceManager
    val query: Query = pm.newQuery((new MediaFile).getClass)
    query.setOrdering("date desc")
    val mediaFiles: JavaList[MediaFile] = try {
      val resultList: JavaList[MediaFile] = query.execute.asInstanceOf[JavaList[MediaFile]]
      resultList.size; resultList
    } catch {
      case e: Exception => { println(e.toString); Nil.asInstanceOf[JavaList[MediaFile]] }
    }
    finally {
      pm.close
    }
    val mediaInfos: JavaList[BlobInfo] = new java.util.ArrayList[BlobInfo]
    for (i <- 0 until mediaFiles.size) {
      mediaInfos.add(blobInfoFactory.loadBlobInfo(new BlobKey(mediaFiles.get(i).blobKey)))
    }
    (Map("mediaFiles" -> mediaFiles, "mediaInfos" -> mediaInfos), "list-media")
  }

  def deleteBlob(key: String): (Map[String, AnyRef], String) = {
    val pm: PersistenceManager = PMF.getInstance.getPersistenceManager
    blobstoreService.delete(new BlobKey(key))
    MediaFileDAO.removeByKey(key)
    (Map.empty[String, AnyRef], "list-media")
  }



  def editSong(label: String): (Map[String, AnyRef], String) = {
    val song = SongDAO.getSongByLabel(label)
    val lilypond = LilypondDAO.getLilypondByLabel(label)
    val lyrics = if (song.getLyrics != null) song.getLyrics.getValue else ""
    (Map("song" -> song, "lilypond" -> (if (lilypond.getLilytext != null) lilypond.getLilytext.getValue else ""),
    		"lyrics" -> lyrics, "label" -> label), "edit-song")
  }

  def deleteAsk(label: String): (Map[String, AnyRef], String) = {
    (Map("label" -> label), "delete-ask")
  }

  def deleteSong(label: String): (Map[String, AnyRef], String) = {
    val removed = SongDAO.removeByLabel(label)
    (Map("removed" -> removed.toString), "delete-song")
  }
}
